home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Vertigo / Common / Sources / MacPrint.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-24  |  12.4 KB  |  573 lines

  1. #include <ctype.h>
  2. #include <LowMem.h>
  3. #include <NumberFormatting.h>
  4. #include <QDOffscreen.h>
  5. #include <string.h>
  6. #include <string_io.h>
  7. #include "MacPrint.h"
  8.  
  9.  
  10.  
  11.  
  12.  
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16.  
  17. // how many pixels should we let free for the menu bar?
  18. #define kLeaveFreeAtTop    21
  19.  
  20. #define kGlobalsID                 ('FDj™')
  21. #define kFontID                    ('Fon™')
  22.  
  23. #define kReinitInterval            (120)
  24.  
  25. #define GLOBALS_ROW                *(SInt16*)0x0A80
  26. #define GLOBALS_COL                *(SInt16*)0x0A82
  27.  
  28. typedef struct MacPrintFont
  29. {
  30.     UInt32                id;
  31.     UInt16                numChars;
  32.     UInt16                offset;
  33.     UInt8                data[];
  34. } MacPrintFont, *MacPrintFontPtr;
  35.  
  36. typedef struct MacPrintGlobals
  37. {
  38.     UInt32                id;
  39.     UInt8                *pixBase;
  40.     MacPrintFontPtr     font;
  41.     UInt32                ticksToReinit;
  42.     UInt32                rowBytes;
  43.     UInt16                depth;
  44.     SInt16                maxrow;
  45.     SInt16                maxcol;
  46. } MacPrintGlobals;
  47.  
  48. typedef struct VPrintfInfo
  49. {
  50.     UInt32    len;
  51. } VPrintfInfo;
  52.  
  53. extern void vdprintf(const char *format,va_list arg);
  54.  
  55. static void MacPrint(char *str);
  56. static void MacPrint_init(void);
  57. static void MacPrint_initqd(void);
  58. static MacPrintFontPtr GetFontPointer(void);
  59. static UInt32 *GetLookupTable(void);
  60. static int vprintf_write_string(__file_handle handle,unsigned char *buffer,size_t *count,__idle_proc idle_proc);
  61.  
  62. #ifdef __cplusplus
  63. }
  64. #endif
  65.  
  66.  
  67.  
  68.  
  69.  
  70. static UInt8                gPrintTable[256];
  71. static MacPrintGlobals        globals;
  72.  
  73.  
  74.  
  75.  
  76.  
  77. void MacPrint(char *str)
  78. {
  79.     MacPrintFontPtr     font;
  80.     UInt8                 *charPtr;
  81.     UInt8                *destPtr;
  82.     SInt16                charRow;
  83.     SInt16                charsInString;
  84.     SInt16                fontOffset;
  85.     SInt32                i;
  86.     char                charByte;
  87.     char                theChar;
  88.     SInt32                *longPtr;
  89.     SInt16                *shortPtr;
  90.     UInt32                *nibbleTable;
  91.     SInt16                nibbleIndex;
  92.     SInt16                bitCount;
  93.     
  94.     
  95.     if (globals.id != kGlobalsID)
  96.         MacPrint_init();
  97.     
  98.     if (LMGetTicks() > globals.ticksToReinit)
  99.         MacPrint_initqd();
  100.     
  101.     charsInString = strlen(str);
  102.     if (charsInString == 0)
  103.         return;
  104.     
  105.     font = globals.font;
  106.     fontOffset = font->offset;
  107.     
  108.     nibbleTable = GetLookupTable();
  109.     for (i = 0; i < charsInString; i++) // loop through the string
  110.     {
  111.         theChar = str[i];
  112.         
  113.         if ((theChar == '\n') || (theChar == '\r'))
  114.         {
  115.             GLOBALS_ROW += 1;
  116.             if (GLOBALS_ROW > globals.maxrow)
  117.                 GLOBALS_ROW = 0;
  118.             
  119.             GLOBALS_COL = 0;
  120.         }
  121.         else
  122.         {
  123.             charPtr = font->data + 8 * (theChar - fontOffset);
  124.             if (((UInt8)theChar - fontOffset) > font->numChars)
  125.                 charPtr = font->data + 8 * ('#' - fontOffset);
  126.             
  127.             destPtr = globals.pixBase + (GLOBALS_COL * globals.depth) + (GLOBALS_ROW * globals.rowBytes * 8);
  128.             switch (globals.depth)
  129.             {
  130.                 case 8: // 256 colors/greys
  131.                     charRow = 8;
  132.                     while(charRow--)
  133.                     {
  134.                         charByte = *charPtr++;
  135.                         
  136.                         longPtr = (SInt32 *)destPtr;
  137.                         
  138.                         nibbleIndex = ((SInt16)charByte) >> 4;
  139.                         *longPtr++ = nibbleTable[nibbleIndex];
  140.                         
  141.                         nibbleIndex = ((SInt16)charByte) & 0x0F;
  142.                         *longPtr   = nibbleTable[nibbleIndex];
  143.                         destPtr += globals.rowBytes;
  144.                     }
  145.                     
  146.                     longPtr = (SInt32 *)destPtr;
  147.                     
  148.                     *longPtr++ = -1L;
  149.                     *longPtr++ = -1L;
  150.                     break;
  151.                 
  152.                 case 16: // thousands
  153.                     charRow = 8;
  154.                     while(charRow--)
  155.                     {
  156.                         charByte = *charPtr++;
  157.                         
  158.                         shortPtr = (SInt16 *)destPtr;
  159.  
  160.                         *shortPtr++ = ((charByte & (1 << 7)) != 0) ? 0 : -1;
  161.                         *shortPtr++ = ((charByte & (1 << 6)) != 0) ? 0 : -1;
  162.                         *shortPtr++ = ((charByte & (1 << 5)) != 0) ? 0 : -1;
  163.                         *shortPtr++ = ((charByte & (1 << 4)) != 0) ? 0 : -1;
  164.                         *shortPtr++ = ((charByte & (1 << 3)) != 0) ? 0 : -1;
  165.                         *shortPtr++ = ((charByte & (1 << 2)) != 0) ? 0 : -1;
  166.                         *shortPtr++ = ((charByte & (1 << 1)) != 0) ? 0 : -1;
  167.                         *shortPtr++ = ((charByte & (1 << 0)) != 0) ? 0 : -1;
  168.                         
  169.                         destPtr += globals.rowBytes;
  170.                     }
  171.  
  172.                     longPtr = (SInt32 *)destPtr;
  173.                     *longPtr++ = 0L; *longPtr++ = 0L; *longPtr++ = 0L; *longPtr++ = 0L;
  174.                     break;
  175.  
  176.                     
  177.                 case 32: // millions
  178.                     charRow = 8;
  179.                     while(charRow--)
  180.                     {
  181.                         charByte = *charPtr++;
  182.                         
  183.                         longPtr = (SInt32 *)destPtr;
  184.                         
  185.                         for (bitCount = 8; bitCount > 0; bitCount --)
  186.                             *longPtr++ = 
  187.                                 ((charByte & (1 << bitCount)) != 0) ? 0L : -1L;
  188.                         
  189.  
  190.                         destPtr += globals.rowBytes;
  191.                     }
  192.  
  193.                     longPtr = (SInt32 *)destPtr;
  194.                     *longPtr++ = 0L; *longPtr++ = 0L; *longPtr++ = 0L; *longPtr++ = 0L;
  195.                     *longPtr++ = 0L; *longPtr++ = 0L; *longPtr++ = 0L; *longPtr++ = 0L;
  196.                     break;
  197.             }
  198.             
  199.             GLOBALS_COL += 1;
  200.             if (GLOBALS_COL > globals.maxcol)
  201.             {
  202.                 GLOBALS_ROW += 1;
  203.                 if (GLOBALS_ROW > globals.maxrow)
  204.                     GLOBALS_ROW = 0;
  205.                 
  206.                 GLOBALS_COL = 0;
  207.             }
  208.         }
  209.     }
  210. }
  211.  
  212.  
  213.  
  214.  
  215.  
  216. void MacPrint_printf(const char *format,...)
  217. {
  218.     va_list        arg;
  219.     
  220.     
  221.     va_start(arg,format);
  222.     MacPrint_vprintf(format,arg);
  223.     va_end(arg);
  224. }
  225.  
  226.  
  227.  
  228.  
  229.  
  230. void MacPrint_vprintf(const char *format,va_list arg)
  231. {
  232.     if (*(SInt8*)0x910 <= 0)
  233.     {
  234.         char        text[sizeof(VPrintfInfo) + 513];
  235.         VPrintfInfo    *info = (VPrintfInfo*)&text[0];
  236.         SInt32        len;
  237.         FILE        file;
  238.         
  239.         
  240.         info->len = 0;
  241.         
  242.         __open_string_file(&file,&text[sizeof(VPrintfInfo)],(sizeof(text) - 1) - sizeof(VPrintfInfo),__writing);
  243.         file.write_proc = vprintf_write_string;
  244.         
  245.         len = vfprintf(&file,format,arg);
  246.         len -= info->len;
  247.         
  248.         if (len > 0)
  249.         {
  250.             text[sizeof(VPrintfInfo) + len] = '\0';
  251.             MacPrint(&text[sizeof(VPrintfInfo)]);
  252.         }
  253.     }
  254.     
  255.     #undef vdprintf
  256.     vdprintf(format,arg);
  257. }
  258.  
  259.  
  260.  
  261.  
  262.  
  263. void MacPrint_printmem(const void *data,size_t len)
  264. {
  265.     char        bin2hex[] = "0123456789ABCDEF";
  266.     char        ascii[17],hex[41],*hstr,*astr;
  267.     Boolean        partial = (len < 16);
  268.     UInt32        spaces;
  269.     UInt8        byte;
  270.     
  271.     
  272.     // Print header line.
  273.     MacPrint_printf("Displaying %lu bytes from %08lX\r",len,data);
  274.     
  275.     // Print full lines.
  276.     for (ascii[16] = '\0';len >= 16;len -= 16,(UInt8*)data += 16)
  277.     {
  278.         for (UInt32 index = 0;index < 16;index++)
  279.             ascii[index] = gPrintTable[*((UInt8*)data + index)];
  280.         
  281.         MacPrint_printf("%08lX  %04X %04X %04X %04X  %04X %04X %04X %04X  '%s'\r",data,*((UInt16*)data + 0),
  282.                 *((UInt16*)data + 1),*((UInt16*)data + 2),*((UInt16*)data + 3),*((UInt16*)data + 4),
  283.                 *((UInt16*)data + 5),*((UInt16*)data + 6),*((UInt16*)data + 7),ascii);
  284.     }
  285.     
  286.     // Print remainder/partial line.
  287.     if (len > 0)
  288.     {
  289.         spaces = 0;
  290.         hstr = &hex[0];
  291.         astr = &ascii[0];
  292.         for (UInt32 index = 0;index < len;index++)
  293.         {
  294.             spaces = 0;
  295.             byte = *((UInt8*)data + index);
  296.             *astr++ = gPrintTable[byte];
  297.             *hstr++ = bin2hex[byte >> 4];
  298.             *hstr++ = bin2hex[byte & 15];
  299.             
  300.             if ((index & 7) == 7)
  301.             {
  302.                 *hstr++ = ' ';
  303.                 spaces += 1;
  304.             }
  305.             
  306.             if ((index & 1) == 1)
  307.             {
  308.                 *hstr++ = ' ';
  309.                 spaces += 1;
  310.             }
  311.         }
  312.         
  313.         while(spaces < 2)
  314.         {
  315.             *hstr++ = ' ';
  316.             spaces += 1;
  317.         }
  318.         
  319.         *hstr = '\0';
  320.         *astr = '\0';
  321.         
  322.         MacPrint_printf("%08lX  %s%*s'%s'\r",data,hex,partial ? 0 : (42 - strlen(hex)),"",ascii);
  323.     }
  324. }
  325.  
  326.  
  327.  
  328.  
  329.  
  330. void MacPrint_fprintf(const char *log,const char *format,...)
  331. {
  332.     #pragma unused(log)
  333.     va_list        arg;
  334.     
  335.     
  336.     va_start(arg,format);
  337.     MacPrint_vprintf(format,arg);
  338.     va_end(arg);
  339. }
  340.  
  341.  
  342.  
  343.  
  344.  
  345. void MacPrint_vfprintf(const char *log,const char *format,va_list arg)
  346. {
  347.     #pragma unused(log)
  348.     MacPrint_vprintf(format,arg);
  349. }
  350.  
  351.  
  352.  
  353.  
  354.  
  355. void MacPrint_fprintmem(const char *log,const void *data,size_t len)
  356. {
  357.     #pragma unused(log)
  358.     MacPrint_printmem(data,len);
  359. }
  360.  
  361.  
  362. #if 0
  363. #pragma mark -
  364. #endif
  365.  
  366.  
  367. static void MacPrint_init(void)
  368. {
  369.     for (UInt32 index = 0;index < 256;index++)
  370.         gPrintTable[index] = (index & 0x80) ? '.' : isprint(index) ? index : '.';
  371.     
  372.     globals.id = 0;
  373.     globals.font = GetFontPointer();
  374.     
  375.     MacPrint_initqd();
  376.     
  377.     if (*(UInt16*)0x0A7E != 0x4D50)
  378.     {
  379.         GLOBALS_ROW = 0;
  380.         GLOBALS_COL = 0;
  381.         *(UInt16*)0x0A7E = 0x4D50;
  382.     }
  383.     
  384.     globals.id = kGlobalsID;    // these globals are valid
  385. }
  386.  
  387.  
  388.  
  389.  
  390.  
  391. static void MacPrint_initqd(void)
  392. {
  393.     GDHandle        gdh;
  394.     PixMapHandle    pmh;
  395.     
  396.     
  397.     gdh = GetMainDevice();
  398.     pmh = (**gdh).gdPMap;
  399.  
  400.     globals.pixBase  = (UInt8*)GetPixBaseAddr(pmh);
  401.     globals.depth    = (**pmh).pixelSize;
  402.     globals.rowBytes = (0x3fff & (**pmh).rowBytes);
  403.     globals.maxrow   = ((**pmh).bounds.bottom - (**pmh).bounds.top - kLeaveFreeAtTop) / 8 - 1;
  404.     globals.maxcol   = (((**pmh).bounds.right - (**pmh).bounds.left) / 8) - 1;
  405.     globals.pixBase += (globals.rowBytes * kLeaveFreeAtTop);
  406.     
  407.     globals.ticksToReinit = LMGetTicks() + kReinitInterval;
  408.  
  409.     if (GLOBALS_COL > globals.maxcol)
  410.     {
  411.         GLOBALS_ROW += 1;
  412.         if (GLOBALS_ROW > globals.maxrow)
  413.             GLOBALS_ROW = 0;
  414.         
  415.         GLOBALS_COL = 0;
  416.     }
  417.     
  418.     if (GLOBALS_ROW > globals.maxrow)
  419.         GLOBALS_ROW = GLOBALS_COL = 0;
  420. }
  421.  
  422.  
  423.  
  424.  
  425.  
  426. static MacPrintFontPtr GetFontPointer(void)
  427. {
  428.     static UInt16 theFont[] = {
  429.         0x466F, 0x6EAA, 0x005A, 0x0020, // id1, id2, numChars, offset
  430.         0x0000, 0x0000, 0x0000, 0x0000, // blank
  431.         0x1818, 0x1818, 0x1800, 0x1800, // !
  432.         0x1414, 0x0000, 0x0000, 0x0000, // "
  433.         0x2424, 0x7E24, 0x7E24, 0x2400, // #
  434.         0x183E, 0x583C, 0x1A7C, 0x1800, // $
  435.         0x43A6, 0x4C18, 0x3265, 0xC200, // %
  436.         0x386C, 0x306A, 0x6C6A, 0x3000, // &
  437.         0x1818, 0x0800, 0x0000, 0x0000, // '
  438.         0x1830, 0x3030, 0x3030, 0x1800, // (
  439.         0x180C, 0x0C0C, 0x0C0C, 0x1800, // )
  440.         0x185A, 0x3C18, 0x3C5A, 0x1800, // *
  441.         0x0018, 0x187E, 0x1818, 0x0000, // +
  442.         0x0000, 0x0000, 0x1818, 0x0810, // ,
  443.         0x0000, 0x003C, 0x0000, 0x0000, // -
  444.         0x0000, 0x0000, 0x0018, 0x1800, // .
  445.         0x0006, 0x0C18, 0x3060, 0x0000, // /
  446.         0x3C66, 0x6E76, 0x6666, 0x3C00, // 0
  447.         0x0C3C, 0x0C0C, 0x0C0C, 0x0C00, // 1
  448.         0x3C66, 0x060C, 0x1830, 0x7E00, // 2
  449.         0x3C66, 0x060C, 0x0666, 0x3C00, // 3
  450.         0x0C1C, 0x3C6C, 0x7E0C, 0x0C00, // 4
  451.         0x7E60, 0x7C06, 0x0666, 0x3C00, // 5
  452.         0x3C60, 0x607C, 0x6666, 0x3C00, // 6
  453.         0x7E0C, 0x0C18, 0x1830, 0x3000, // 7
  454.         0x3C66, 0x663C, 0x6666, 0x3C00, // 8
  455.         0x3C66, 0x663E, 0x0606, 0x3C00, // 9
  456.         0x0000, 0x1818, 0x0018, 0x1800, // :
  457.         0x0018, 0x1800, 0x1818, 0x0810, // ;
  458.         0x0C18, 0x3060, 0x3018, 0x0C00, // <
  459.         0x0000, 0x003C, 0x003C, 0x0000, // =
  460.         0x3018, 0x0C06, 0x0C18, 0x3000, // >
  461.         0x3C66, 0x060C, 0x1800, 0x1800, // ?
  462.         0x3E41, 0x5D55, 0x5E40, 0x3E00, // @
  463.         0x3C66, 0x667E, 0x6666, 0x6600, // A
  464.         0x7C66, 0x667C, 0x6666, 0x7C00, // B
  465.         0x3C66, 0x6060, 0x6066, 0x3C00, // C
  466.         0x7C66, 0x6666, 0x6666, 0x7C00, // D
  467.         0x7E60, 0x6078, 0x6060, 0x7E00, // E
  468.         0x7E60, 0x6078, 0x6060, 0x6000, // F
  469.         0x3C66, 0x606E, 0x6666, 0x3C00, // G
  470.         0x6666, 0x667E, 0x6666, 0x6600, // H
  471.         0x3C18, 0x1818, 0x1818, 0x3C00, // I
  472.         0x7E06, 0x0606, 0x0666, 0x3C00, // J
  473.         0x6666, 0x6C78, 0x6C66, 0x6600, // K
  474.         0x6060, 0x6060, 0x6060, 0x7E00, // L
  475.         0x6276, 0x6A62, 0x6262, 0x6200, // M
  476.         0x6272, 0x6A66, 0x6262, 0x6200, // N
  477.         0x3C66, 0x6666, 0x6666, 0x3C00, // O
  478.         0x7C66, 0x667C, 0x6060, 0x6000, // P
  479.         0x3C66, 0x6666, 0x6E6E, 0x3E00, // Q
  480.         0x7C66, 0x667C, 0x6666, 0x6600, // R
  481.         0x3C66, 0x603C, 0x0666, 0x3C00, // S
  482.         0x7E18, 0x1818, 0x1818, 0x1800, // T
  483.         0x6666, 0x6666, 0x6666, 0x3E00, // U
  484.         0x6666, 0x6666, 0x6624, 0x1800, // V
  485.         0x6262, 0x6262, 0x6A76, 0x6200, // W
  486.         0x6666, 0x2418, 0x2466, 0x6600, // X
  487.         0x6666, 0x2418, 0x1818, 0x1800, // Y
  488.         0x7E06, 0x0C18, 0x3060, 0x7E00, // Z
  489.         0x1C10, 0x1010, 0x1010, 0x1C00, // [
  490.         0x4060, 0x3018, 0x0C06, 0x0200, // '\'
  491.         0x3808, 0x0808, 0x0808, 0x3800, // ]
  492.         0x1C36, 0x6300, 0x0000, 0x0000, // ^
  493.         0x0000, 0x0000, 0x0000, 0xFF00, // _
  494.         0x3018, 0x0C00, 0x0000, 0x0000, // `
  495.         0x3C66, 0x667E, 0x6666, 0x6600, // A
  496.         0x7C66, 0x667C, 0x6666, 0x7C00, // B
  497.         0x3C66, 0x6060, 0x6066, 0x3C00, // C
  498.         0x7C66, 0x6666, 0x6666, 0x7C00, // D
  499.         0x7E60, 0x6078, 0x6060, 0x7E00, // E
  500.         0x7E60, 0x6078, 0x6060, 0x6000, // F
  501.         0x3C66, 0x606E, 0x6666, 0x3C00, // G
  502.         0x6666, 0x667E, 0x6666, 0x6600, // H
  503.         0x3C18, 0x1818, 0x1818, 0x3C00, // I
  504.         0x7E06, 0x0606, 0x0666, 0x3C00, // J
  505.         0x6666, 0x6C78, 0x6C66, 0x6600, // K
  506.         0x6060, 0x6060, 0x6060, 0x7E00, // L
  507.         0x6276, 0x6A62, 0x6262, 0x6200, // M
  508.         0x6272, 0x6A66, 0x6262, 0x6200, // N
  509.         0x3C66, 0x6666, 0x6666, 0x3C00, // O
  510.         0x7C66, 0x667C, 0x6060, 0x6000, // P
  511.         0x3C66, 0x6666, 0x6E6E, 0x3E00, // Q
  512.         0x7C66, 0x667C, 0x6666, 0x6600, // R
  513.         0x3C66, 0x603C, 0x0666, 0x3C00, // S
  514.         0x7E18, 0x1818, 0x1818, 0x1800, // T
  515.         0x6666, 0x6666, 0x6666, 0x3E00, // U
  516.         0x6666, 0x6666, 0x6624, 0x1800, // V
  517.         0x6262, 0x6262, 0x6A76, 0x6200, // W
  518.         0x6666, 0x2418, 0x2466, 0x6600, // X
  519.         0x6666, 0x2418, 0x1818, 0x1800, // Y
  520.         0x7E06, 0x0C18, 0x3060, 0x7E00, // Z
  521.     };
  522.  
  523.     return (MacPrintFontPtr)theFont;
  524. }
  525.  
  526.  
  527.  
  528.  
  529.  
  530. UInt32 *GetLookupTable(void)
  531. {
  532.     static UInt32 table[] = {
  533.         ~0x00000000, 
  534.         ~0x000000FF,
  535.         ~0x0000FF00,
  536.         ~0x0000FFFF,
  537.         ~0x00FF0000,
  538.         ~0x00FF00FF,
  539.         ~0x00FFFF00,
  540.         ~0x00FFFFFF,
  541.         ~0xFF000000, 
  542.         ~0xFF0000FF,
  543.         ~0xFF00FF00,
  544.         ~0xFF00FFFF,
  545.         ~0xFFFF0000,
  546.         ~0xFFFF00FF,
  547.         ~0xFFFFFF00,
  548.         ~0xFFFFFFFF
  549.     };
  550.     
  551.     
  552.     return table;
  553. }
  554.  
  555.  
  556.  
  557.  
  558.  
  559. int vprintf_write_string(__file_handle handle,unsigned char *buffer,size_t *count,__idle_proc idle_proc)
  560. {
  561.     VPrintfInfo    *info = (VPrintfInfo*)((UInt32)buffer - sizeof(VPrintfInfo));
  562.     
  563.     
  564.     if (*count > 0)
  565.     {
  566.         buffer[*count] = '\0';
  567.         MacPrint((char*)buffer);
  568.     }
  569.     
  570.     info->len += *count;
  571.     return(__no_io_error);
  572. }
  573.